home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mush-7.1.1 / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-02  |  8.7 KB  |  358 lines

  1. /* @(#)main.c    (c) copyright 10/18/86 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4. #include "options.h"
  5.  
  6. #if defined(sun) && defined(M_DEBUG)
  7. cpu()
  8. {
  9.     print("CPU time limit exceeded!\n");
  10. }
  11. #endif /* sun && DEBUG */
  12.  
  13. #ifdef LCKDFLDIR
  14. extern char *lckdfldir;
  15. #endif /* LCKDFLDIR */
  16.  
  17. #ifdef DOT_LOCK
  18. int sgid;
  19. #ifdef BSD
  20. int rgid;
  21. #endif /* BSD */
  22. #endif /* DOT_LOCK */
  23.  
  24. /*ARGSUSED*/   /* we ignore envp */
  25. main(argc, argv)
  26. int argc;
  27. char *argv[];
  28. {
  29.     int              n;
  30.     char           buf[MAXPATHLEN];
  31.     register char    *p;
  32.     struct mush_flags Flags;
  33.  
  34. #ifndef INTERNAL_MALLOC
  35.     extern char *stackbottom;    /* used by xfree() */
  36.  
  37.     stackbottom = (char *) &argc;
  38. #endif /* INTERNAL_MALLOC */
  39.  
  40. #ifdef LCKDFLDIR
  41.     lckdfldir = LCKDFLDIR;
  42. #endif /* LCKDFLDIR */
  43.     if (prog_name = rindex(*argv, '/'))
  44.     prog_name++;
  45.     else
  46.     prog_name = *argv;
  47.  
  48.     (void) signal(SIGBUS,  bus_n_seg);
  49.     (void) signal(SIGSEGV, bus_n_seg);
  50.     (void) signal(SIGPIPE, SIG_IGN); /* if pager is terminated before end */
  51.  
  52. #if defined(sun) && defined(M_DEBUG)
  53.     (void) signal(SIGXCPU, cpu);
  54.  
  55.     if (p = getenv("MALLOC_DEBUG"))
  56.     malloc_debug(atoi(p));
  57.     else
  58.     malloc_debug(0);
  59. #endif /* sun && debug */
  60.  
  61.     if (!isatty(0))
  62.     turnon(glob_flags, REDIRECT);
  63.     else
  64.     (void) setbuf(stdin, NULL);
  65.  
  66.     (void) cmd_line(strcpy(buf, "set cmd_help"), NULL);
  67.  
  68.     init(); /* must be done before checking mail since "login" is set here */
  69.     mailfile = "";
  70. #ifdef HOMEMAIL
  71.     {
  72.     char *home = do_set(set_options, "home");
  73.     if (!home)
  74.         home = ALTERNATE_HOME;
  75.     strdup(spoolfile, sprintf(buf, "%s/%s", home, MAILFILE));
  76.     }
  77. #else /* HOMEMAIL */
  78.     strdup(spoolfile, sprintf(buf, "%s/%s", MAILDIR, login));
  79. #endif /* HOMEMAIL */
  80.  
  81.     n = preparse_opts(&argc,argv);
  82.  
  83.     /* check for any mail at all and exit if we're not continuing */
  84.     if (!n) {
  85.     struct stat statb;
  86.     if (stat(spoolfile, &statb) || statb.st_size == 0) {
  87.         (void) printf("No mail for %s.\n", login);
  88.         exit(0);
  89.     }
  90.     }
  91.  
  92. #ifdef DOT_LOCK
  93.     sgid = getegid();
  94. #ifdef BSD
  95.     rgid = getgid();
  96.     setregid(sgid, rgid);
  97. #else
  98.     setgid(getgid());
  99. #endif /* BSD */
  100. #endif /* DOT_LOCK */
  101.  
  102.     parse_options(&argv, &Flags);
  103.  
  104.     set_cwd();
  105.  
  106.     if (Flags.init_file)
  107.     (void) cmd_line(sprintf(buf, "source %s", Flags.init_file), msg_list);
  108.     if (Flags.source_rc > 0) {
  109.     /* use cmd_line() in case DEFAULT_RC has expandable chars */
  110.     (void) cmd_line(sprintf(buf, "source %s", DEFAULT_RC), msg_list);
  111.     }
  112.     if (Flags.source_rc > -1)
  113.     (void) source(0, DUBL_NULL);
  114.     mailfile = Flags.folder;
  115.  
  116.     if (*spoolfile != '/') {
  117.     n = 1;
  118.     p = getpath(spoolfile, &n);
  119.     if (n == -1)
  120.         (void) fputs(p, stderr), exit(1);
  121.     else if (n)
  122.         (void) fprintf(stderr, "\"%s\" is a directory.\n", p), exit(1);
  123.     else if (*p != '/') {
  124.         /* if it still isn't a full path, make it one */
  125.         char *wd = do_set(set_options, "cwd");
  126.         if (*wd) {
  127.         (void) sprintf(buf, "%s/%s", wd, p);
  128.         strdup(spoolfile, buf);
  129.         } else
  130.         strdup(spoolfile, p);
  131.     } else
  132.         strdup(spoolfile, p);
  133.     }
  134.  
  135. #ifdef SUNTOOL
  136.     if (istool) {
  137.     make_tool();
  138.     turnon(glob_flags, DO_SHELL);
  139.     turnoff(glob_flags, REDIRECT); /* -- SunOS-4.0 has a problem here */
  140.     }
  141. #endif /* SUNTOOL */
  142.  
  143.     /* now we're ready for I/O */
  144.     if (isoff(glob_flags, REDIRECT)) {
  145.     /* make sure we can always recover from no echo mode */
  146.     (void) signal(SIGINT, catch);
  147.     (void) signal(SIGQUIT, catch);
  148.     (void) signal(SIGHUP, catch);
  149.     if (istool)
  150.         turnon(glob_flags, ECHO_FLAG);
  151.     tty_settings();
  152. #ifdef SIGCONT
  153.     (void) signal(SIGTSTP, stop_start); /* this will take care of SIGCONT */
  154. #endif /* SIGCONT */
  155.     /* echo_off() checks to see if echo_flg is set, so don't worry */
  156.     echo_off();
  157.     }
  158.  
  159.     if (!istool && ison(glob_flags, IS_SENDING)) {
  160.     char recipients[BUFSIZ], *mailv[16];
  161.     (void) argv_to_string(recipients, argv);
  162.     fix_up_addr(recipients);
  163.     mailv[0] = "mail";
  164.     n = 1;
  165.     if (ison(Flags.flg, VERBOSE))
  166.         mailv[n++] = "-v";
  167.     if (Flags.Subj && *(Flags.Subj)) {
  168.         mailv[n++] = "-s";
  169.         mailv[n++] = Flags.Subj;
  170.     }
  171.     if (Flags.Cc && *(Flags.Cc)) {
  172.         fix_up_addr(Flags.Cc);
  173.         mailv[n++] = "-c";
  174.         mailv[n++] = Flags.Cc;
  175.     }
  176.     if (Flags.Bcc && *(Flags.Bcc)) {
  177.         fix_up_addr(Flags.Bcc);
  178.         mailv[n++] = "-b";
  179.         mailv[n++] = Flags.Bcc;
  180.     }
  181.     if (ison(Flags.flg, NO_SIGN))
  182.         mailv[n++] = "-u";
  183.     if (ison(Flags.flg, SEND_NOW))
  184.         mailv[n++] = "-U";
  185.     if (Flags.draft) {
  186.         if (isoff(Flags.flg, SEND_NOW))
  187.         mailv[n++] = "-E";
  188.         mailv[n++] = "-h";
  189.         mailv[n++] = Flags.draft;
  190.     }
  191.     mailv[n++] = recipients;
  192.     mailv[n] = NULL;
  193.     /* set now in case user is not running shell, but is running debug */
  194. #ifndef SUNTOOL
  195.     (void) signal(SIGCHLD, sigchldcatcher);
  196. #endif /* SUNTOOL */
  197.     if (!setjmp(jmpbuf))
  198.         (void) do_mail(n, mailv, msg_list);
  199.     /* do shell set from above: "mush -S user" perhaps */
  200.     if (isoff(glob_flags, DO_SHELL) && !*mailfile) {
  201.         if (isoff(glob_flags, REDIRECT))
  202.         echo_on();
  203.         exit(0);
  204.     }
  205.     }
  206.     turnoff(glob_flags, IS_SENDING); /* no longer sending mail; running shell */
  207.  
  208.     if (ison(glob_flags, REDIRECT)
  209.         && (!Flags.src_file || !Flags.src_n_exit)) {
  210.     puts("You can't redirect input unless you're sending mail.");
  211.     puts("If you want to run a shell with redirection, use \"-i\"");
  212.     cleanup(0);
  213.     }
  214.     if (!*mailfile) {
  215.     strdup(mailfile, spoolfile);
  216.     if (!mail_size() && isoff(glob_flags, DO_SHELL)) {
  217.         /* we know it's not the spool file here */
  218.         (void) printf("No mail in %s.\n", mailfile);
  219.         echo_on(), exit(0);
  220.     }
  221.     }
  222.  
  223.     if (!hdrs_only) {
  224.     /* catch will test DO_SHELL and try to longjmp if set.  this is a
  225.      * transition state from no-shell to do-shell to ignore sigs to
  226.      * avoid a longjmp botch.  Note setjmp isn't called until do_loop().
  227.      */
  228.     turnon(glob_flags, IGN_SIGS);
  229. #ifdef CURSES
  230.     if (ison(glob_flags, PRE_CURSES))
  231.         (void) curses_init(0, DUBL_NULL);
  232.     turnoff(glob_flags, PRE_CURSES);
  233. #endif /* CURSES */
  234.     }
  235.  
  236.     /* find a free tmpfile */
  237.     if (!(p = getdir(do_set(set_options, "tmpdir"))))
  238. alted:
  239.     p = ALTERNATE_HOME;
  240.     {
  241.     int pid = getpid();
  242.     while (!Access(sprintf(tempfile, "%s/.%s%d", p, prog_name, pid++), F_OK))
  243.     ;
  244.     }
  245.     /* just create the file, make sure it's empty.  It'll close later and
  246.      * be reopened for reading only.
  247.      */
  248.     if (!(tmpf = mask_fopen(tempfile, "w"))) {
  249.     if (strcmp(p, ALTERNATE_HOME))
  250.         goto alted;
  251.     error("Can't create tempfile %s", tempfile);
  252.     cleanup(0);
  253.     }
  254.  
  255.     /* do pseudo-intelligent stuff with certain signals */
  256.     (void) signal(SIGINT,  catch);
  257.     (void) signal(SIGQUIT, catch);
  258.     (void) signal(SIGHUP,  catch);
  259.  
  260.     if (!hdrs_only && !istool && (!Flags.src_file || !Flags.src_n_exit) &&
  261.     !glob(do_set(set_options, "quiet"), "{,{,*[ \\,]}startup{,[ \\,]*}}"))
  262.     (void) printf("%s: Type '?' for help.\n", check_internal("version"));
  263.  
  264.     (void) sprintf(buf, "folder %s %s", Flags.f_flags, mailfile);
  265.     if ((argv = mk_argv(buf, &argc, TRUE)) && argc > 0) {
  266.     if (folder(argc, argv, NULL) == -1 && isoff(glob_flags, DO_SHELL)) {
  267.         if (iscurses)
  268.         putchar('\n');
  269.         turnoff(glob_flags, IGN_SIGS), cleanup(0);
  270.     }
  271. #ifdef CURSES
  272.     if (iscurses)
  273.         (void) curses_help_msg(TRUE);
  274. #endif /* CURSES */
  275.     free_vec(argv);
  276.     }
  277.  
  278.     if (hdrs_only) {
  279.     (void) sprintf(buf, "headers %s", hdrs_only);
  280.     if (argv = make_command(buf, TRPL_NULL, &argc))
  281.         (void) do_hdrs(argc, argv, NULL);
  282.     cleanup(0);
  283.     }
  284.  
  285.     turnon(glob_flags, DO_SHELL);
  286.     if (istool && msg_cnt)
  287.     set_isread(current_msg);
  288.  
  289.     /* finally, if the user wanted to source a file to execute, do it now */
  290.     if (Flags.src_file) {
  291.     char *s_argv[2];
  292.     s_argv[1] = Flags.src_file;
  293.     (void) source(2, s_argv);
  294.     if (!istool && Flags.src_n_exit)
  295.         cleanup(0);
  296.     }
  297.  
  298. #ifdef SUNTOOL
  299.     if (istool) {
  300.     char buf[16];
  301.     n = 0;
  302.     (void) cmd_line(strcpy(buf, "set tool_help"), NULL);
  303.     if (time_out < 30)
  304.         time_out = 30;
  305.     turnoff(glob_flags, IGN_SIGS);
  306.     (void) do_hdrs(0, DUBL_NULL, NULL);
  307.     timerclear(&(mail_timer.it_interval));
  308.     timerclear(&(mail_timer.it_value));
  309.  
  310.     /*  Reload time with value of timeout upon timer expiration. */
  311.     mail_timer.it_interval.tv_sec = time_out;
  312.  
  313.     mail_timer.it_value.tv_sec = time_out;
  314.     (void) notify_set_itimer_func(tool, do_check,
  315.         ITIMER_REAL, &mail_timer, (struct itimerval *) 0);
  316.     timeout_cursors(FALSE);
  317.     turnoff(glob_flags, DO_UPDATE);
  318.     window_main_loop(tool);
  319.     cleanup(0);
  320.     }
  321. #endif /* SUNTOOL */
  322.     do_loop();
  323. }
  324.  
  325. do_version()
  326. {
  327.     print("%s\n", check_internal("version"));
  328.     return -1;
  329. }
  330.  
  331. /* set the current working directory */
  332. set_cwd()
  333. {
  334.     char cwd[MAXPATHLEN];
  335. #ifndef SYSV
  336.     extern char *getwd();
  337. #else /* SYSV */
  338.     extern char *getcwd();
  339. #endif /* SYSV */
  340.  
  341. #ifndef SYSV
  342.     if (getwd(cwd) == NULL)
  343. #else
  344.     if (getcwd(cwd, MAXPATHLEN) == NULL)
  345. #endif /* SYSV */
  346.     {
  347.     error("set_cwd: %s", cwd);
  348.     (void) un_set(&set_options, "cwd");
  349.     } else {
  350.     char *argv[4];
  351.     argv[0] = "cwd";
  352.     argv[1] = "=";
  353.     argv[2] = cwd;
  354.     argv[3] = NULL;
  355.     (void) add_option(&set_options, argv);
  356.     }
  357. }
  358.